package com.haierp.util;



import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Currency;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.haierp.model.ErpOrder;
import com.haierp.vo.ShippingOrderQueryVO;

public class Money implements Serializable, Comparable {
 private static final long serialVersionUID = 3761410806910104373L;
 public static final String DEFAULT_CURRENCY_CODE = "CNY";
 public static final int DEFAULT_ROUNDING_MODE = 6;
 private static final int[] centFactors = new int[]{1, 10, 100, 1000};
 private static final String DEFAULT_LOCALE = "zh_CN";
 protected static Map<String, Map<String, String>> CURRENCY_DISPLAY_UNIT_MAP = new HashMap();
 public static final Money ZERO;
 private long cent;
 private Currency currency;
 

 static {
     HashMap zhCNMap = new HashMap();
     zhCNMap.put("CNY", "元");
     zhCNMap.put("POINT", "积分");
     CURRENCY_DISPLAY_UNIT_MAP.put("zh_CN", zhCNMap);
     HashMap zhHKMap = new HashMap();
     zhHKMap.put("CNY", "元");
     zhHKMap.put("POINT", "積分");
     CURRENCY_DISPLAY_UNIT_MAP.put("zh_HK", zhHKMap);
     ZERO = new Money(0L);
 }

 public Money() {
     this(0L);
 }

 public Money(long yuan, int cent) {
     this(yuan, cent, Currency.getInstance("CNY"));
 }

 public Money(long cent) {
     this.currency = Currency.getInstance("CNY");
     this.cent = cent;
 }

 public Money(long yuan, int cent, Currency currency) {
     this.currency = currency;
     this.cent = yuan * (long)this.getCentFactor() + (long)(cent % this.getCentFactor());
 }

 public Money(String amount) {
     this(amount, Currency.getInstance("CNY"));
 }

 public Money(String amount, Currency currency) {
     this(new BigDecimal(amount), currency);
 }

 public Money(String amount, Currency currency, int roundingMode) {
     this(new BigDecimal(amount), currency, roundingMode);
 }

 public Money(double amount) {
     this(amount, Currency.getInstance("CNY"));
 }

 public Money(double amount, Currency currency) {
     this.currency = currency;
     this.cent = Math.round(amount * (double)this.getCentFactor());
 }

 public Money(BigDecimal amount) {
     this(amount, Currency.getInstance("CNY"));
 }

 public Money(BigDecimal amount, int roundingMode) {
     this(amount, Currency.getInstance("CNY"), roundingMode);
 }

 public Money(BigDecimal amount, Currency currency) {
     this((BigDecimal)amount, currency, 6);
 }

 public Money(BigDecimal amount, Currency currency, int roundingMode) {
     this.currency = currency;
     this.cent = this.rounding(amount.movePointRight(currency.getDefaultFractionDigits()), roundingMode);
 }

 public BigDecimal getAmount() {
     return BigDecimal.valueOf(this.cent, this.currency.getDefaultFractionDigits());
 }

 public void setAmount(BigDecimal amount) {
     if(amount != null) {
         this.cent = this.rounding(amount.movePointRight(2), 6);
     }

 }

 public long getCent() {
     return this.cent;
 }

 /** @deprecated */
 public Currency getCurrency() {
     return this.currency;
 }

 public String getCurrencyCode() {
     return this.currency.getCurrencyCode();
 }

 public int getCentFactor() {
     return centFactors[this.currency.getDefaultFractionDigits()];
 }

 public boolean equals(Object other) {
     return other instanceof Money && this.equals((Money)other);
 }

 public boolean equals(Money other) {
     return this.currency.equals(other.currency) && this.cent == other.cent;
 }

 public int hashCode() {
     return (int)(this.cent ^ this.cent >>> 32);
 }

 public int compareTo(Object other) {
     return this.compareTo((Money)other);
 }

 public int compareTo(Money other) {
     this.assertSameCurrencyAs(other);
     return this.cent < other.cent?-1:(this.cent == other.cent?0:1);
 }

 public boolean greaterThan(Money other) {
     return this.compareTo(other) > 0;
 }

 public Money add(Money other) {
     this.assertSameCurrencyAs(other);
     return this.newMoneyWithSameCurrency(this.cent + other.cent);
 }

 public Money addTo(Money other) {
     this.assertSameCurrencyAs(other);
     this.cent += other.cent;
     return this;
 }

 public Money subtract(Money other) {
     this.assertSameCurrencyAs(other);
     return this.newMoneyWithSameCurrency(this.cent - other.cent);
 }

 public Money subtractFrom(Money other) {
     this.assertSameCurrencyAs(other);
     this.cent -= other.cent;
     return this;
 }

 public Money multiply(long val) {
     return this.newMoneyWithSameCurrency(this.cent * val);
 }

 public Money multiplyBy(long val) {
     this.cent *= val;
     return this;
 }

 public Money multiply(double val) {
     return this.newMoneyWithSameCurrency(Math.round((double)this.cent * val));
 }

 public Money multiplyBy(double val) {
     this.cent = Math.round((double)this.cent * val);
     return this;
 }

 public Money multiply(BigDecimal val) {
     return this.multiply(val, 6);
 }

 public Money multiplyBy(BigDecimal val) {
     return this.multiplyBy(val, 6);
 }

 public Money multiply(BigDecimal val, int roundingMode) {
     BigDecimal newCent = BigDecimal.valueOf(this.cent).multiply(val);
     return this.newMoneyWithSameCurrency(this.rounding(newCent, roundingMode));
 }

 public Money multiplyBy(BigDecimal val, int roundingMode) {
     BigDecimal newCent = BigDecimal.valueOf(this.cent).multiply(val);
     this.cent = this.rounding(newCent, roundingMode);
     return this;
 }

 public Money divide(double val) {
     return this.newMoneyWithSameCurrency(Math.round((double)this.cent / val));
 }

 public Money divideBy(double val) {
     this.cent = Math.round((double)this.cent / val);
     return this;
 }

 public Money divide(BigDecimal val) {
     return this.divide(val, 6);
 }

 public Money divide(BigDecimal val, int roundingMode) {
     BigDecimal newCent = BigDecimal.valueOf(this.cent).divide(val, roundingMode);
     return this.newMoneyWithSameCurrency(newCent.longValue());
 }

 public Money divideBy(BigDecimal val) {
     return this.divideBy(val, 6);
 }

 public Money divideBy(BigDecimal val, int roundingMode) {
     BigDecimal newCent = BigDecimal.valueOf(this.cent).divide(val, roundingMode);
     this.cent = newCent.longValue();
     return this;
 }

 public Money[] allocate(int targets) {
     Money[] results = new Money[targets];
     Money lowResult = this.newMoneyWithSameCurrency(this.cent / (long)targets);
     Money highResult = this.newMoneyWithSameCurrency(lowResult.cent + 1L);
     int remainder = (int)this.cent % targets;

     int i;
     for(i = 0; i < remainder; ++i) {
         results[i] = highResult;
     }

     for(i = remainder; i < targets; ++i) {
         results[i] = lowResult;
     }

     return results;
 }

 public Money[] allocate(long[] ratios) {
     Money[] results = new Money[ratios.length];
     long total = 0L;

     for(int remainder = 0; remainder < ratios.length; ++remainder) {
         total += ratios[remainder];
     }

     long var8 = this.cent;

     int i;
     for(i = 0; i < results.length; ++i) {
         results[i] = this.newMoneyWithSameCurrency(this.cent * ratios[i] / total);
         var8 -= results[i].cent;
     }

     for(i = 0; (long)i < var8; ++i) {
         ++results[i].cent;
     }

     return results;
 }

 public String toString() {
     return this.getAmount().toString();
 }

 protected void assertSameCurrencyAs(Money other) {
     if(!this.currency.equals(other.currency)) {
         throw new IllegalArgumentException("Money math currency mismatch.");
     }
 }

 protected long rounding(BigDecimal val, int roundingMode) {
     return val.setScale(0, roundingMode).longValue();
 }

 protected Money newMoneyWithSameCurrency(long cent1) {
     Money money = new Money(0.0D, this.currency);
     money.cent = cent1;
     return money;
 }

 public String dump() {
     String lineSeparator = System.getProperty("line.separator");
     StringBuffer sb = new StringBuffer();
     sb.append("cent = ").append(this.cent).append(lineSeparator);
     sb.append("currency = ").append(this.currency);
     return sb.toString();
 }

 public void setCent(long cent) {
     this.cent = cent;
 }

/* public String getDisplayUnit() {
     return this.getDisplayUnit(LocaleUtil.getContext().getLocale());
 }

 public String getDisplayUnit(Locale e) {
     if(e == null) {
         e = LocaleUtil.getContext().getLocale();
     }

     String currencyCode = this.getCurrencyCode();
     Map cMap = (Map)CURRENCY_DISPLAY_UNIT_MAP.get(e.toString());
     if(cMap == null) {
         cMap = (Map)CURRENCY_DISPLAY_UNIT_MAP.get("zh_CN");
     }

     String displayUnit = (String)cMap.get(currencyCode);
     if(displayUnit == null) {
         displayUnit = currencyCode;
     }

     return displayUnit;
 }*/
 
	public static ShippingOrderQueryVO getYeType(List<ErpOrder> ErpOrderPrice) {
		ShippingOrderQueryVO shippingVo = new ShippingOrderQueryVO();
		boolean categoryBoolean = false;
		int finallyType = 0;
		double priceTotall = 0.0;
		double purchaseTotall = 0.0;
		double skuWeight = 0.0;
		double totalWeight = 0.0;
		for (ErpOrder erpOrder : ErpOrderPrice) {
			if (erpOrder.getWeight() != null) {
				skuWeight += erpOrder.getWeight() * erpOrder.getQuantity();
			}
		}
		if (skuWeight > 0) {
			totalWeight = 0D;
			if (skuWeight + 0.33 < 1) { // 不足1磅的按1磅计
				totalWeight = 1;
			} else {
				totalWeight = Math.ceil((skuWeight + 0.33) * 10);
				totalWeight = totalWeight / 10;
			}
		}
		for (ErpOrder erpOrder : ErpOrderPrice) {
			if (!erpOrder.getCategoryName().equals("精品美食")) {
				categoryBoolean = true;
			}
			priceTotall += erpOrder.getSalePrice() * erpOrder.getQuantity();
			if (erpOrder.getPurchasePrice() != null) {
				purchaseTotall += erpOrder.getPurchasePrice() * erpOrder.getQuantity();
			}
		}
		if (categoryBoolean) {
			if ((priceTotall * 0.3) < 50.00) {
				finallyType = 6;
			} else if (finallyType != 6 && priceTotall < 500.00) {
				finallyType = 10;
			} else {
				finallyType = 1;
			}
		}
		if (!categoryBoolean) {
			if (((priceTotall * 0.7) * 0.15) < 50.00) {
				finallyType = 6;
			} else if (finallyType != 6 && priceTotall < 500) {
				finallyType = 10;
			} else {
				finallyType = 1;
			}
		}
		// 最后判别轻奢类包包
		for (ErpOrder erpOrder : ErpOrderPrice) {
			if (erpOrder.getCategoryName().equals("潮流女包") || erpOrder.getCategoryName().equals("时尚男包")
					|| erpOrder.getCategoryName().equals("精品钱包") || erpOrder.getCategoryName().equals("箱包皮具")
					|| erpOrder.getCategoryName().equals("配饰") || erpOrder.getCategoryName().equals("流行饰品")
					|| erpOrder.getCategoryName().equals("美妆护肤") || erpOrder.getCategoryName().equals("面部护肤")|| erpOrder.getCategoryName().equals("高级护肤")
					|| erpOrder.getCategoryName().equals("潮流香水") || erpOrder.getCategoryName().equals("潮流彩妆") || erpOrder.getCategoryName().equals("彩妆香水") || erpOrder.getBrand().contains("MK") || erpOrder.getBrand().contains("Fresh")
					|| erpOrder.getCategoryName().equals("生活电器") || erpOrder.getBrand().contains("Coach") || erpOrder.getCategoryName().equals("鞋靴")) {
				finallyType = 1;
			}
		}
		// 特殊商品固定写入食品线
		if (ErpOrderPrice.size() == 1) {
			if (ErpOrderPrice.get(0).getItemName().contains("牙膏")
					|| ErpOrderPrice.get(0).getItemCode().equals("I0406001Q12753")
					|| ErpOrderPrice.get(0).getItemCode().equals("I0406001Q12709")
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0301001Q12269")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("SKUbag1702201320")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("SKUbag1702202979")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0401001Q13924")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0301001Q13923")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("SKU1702234077")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("SKU1705160100")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0301001Q12002")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0402001Q35622")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0301001Q31915")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0406001Q35621")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0301001Q65945")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0402001Q26831")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0101001Q10513")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("SKU1702244087")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0105001Q10156")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("SKUbag1702202806")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("I0306001Q10442")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("SKU1704080053")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| (ErpOrderPrice.get(0).getItemCode().equals("SKUbag1702202772")
							&& ErpOrderPrice.get(0).getQuantity() == 1)
					|| ErpOrderPrice.get(0).getItemName().contains("新秀丽")) {
				finallyType = 6;
			}
		}
		if (finallyType == 6) {
			priceTotall = NumberUtil.formatDouble2(totalWeight * 2.2);
		} else if (finallyType == 10) {
			priceTotall = NumberUtil.formatDouble2(totalWeight * 3.0);
		} else if (finallyType == 1) {
			priceTotall = NumberUtil.formatDouble2(totalWeight * 3.5);
		}
		shippingVo.setBestType(finallyType);
		shippingVo.setFinallyFreight(priceTotall);
		return shippingVo;
	}
	
	public static ShippingOrderQueryVO getPxType(List<ErpOrder> ErpOrderPrice) {
		//A线和B线 价格无太大差异，A线需要身份证，B线不需要身份证,优选B线 速度时效较快; 如果混装收费按照就高原则；
		ShippingOrderQueryVO shippingVo = new ShippingOrderQueryVO();
		int finallyType = 0;
		double priceTotall = 0.0;
		double skuWeight = 0.0;
		double totalWeight = 0.0;
		double pxFDA = 2.7;//(食品保健品线路)
		double pxBLIF = 2.7;//(生活用品)//(5月A线和5月B线此类目有差异)
		double pxECO = 3.3;//(小家电,普通彩妆,衣服，鞋靴)
		double pxTypeHUA = 3.8;//(轻奢渠道)
		for (ErpOrder erpOrder : ErpOrderPrice) {
			if (erpOrder.getWeight() != null) {
				skuWeight += erpOrder.getWeight() * erpOrder.getQuantity();
			}
		}
		if (skuWeight > 0) {
			totalWeight = 0D;
			if (skuWeight + 0.33 < 1) { // 不足1磅的按1磅计
				totalWeight = 1;
			} else {
				totalWeight = Math.ceil((skuWeight + 0.33) * 10);
				totalWeight = totalWeight / 10;
			}
		}
		if(ErpOrderPrice.size() == 1 && ErpOrderPrice.get(0).getCategoryName().equals("精品美食")) {
			priceTotall = NumberUtil.formatDouble2(totalWeight * pxFDA);
		} else {
			for (ErpOrder erpOrder : ErpOrderPrice) {
				if (erpOrder.getCategoryName().equals("生活用品") || erpOrder.getCategoryName().equals("精美食品")) {
					priceTotall = NumberUtil.formatDouble2(totalWeight * pxBLIF);
					shippingVo.setBestType(8);
				} else if (erpOrder.getCategoryName().equals("生活电器") 
						|| erpOrder.getCategoryName().equals("潮流服饰") || erpOrder.getCategoryName().equals("男装")
						|| erpOrder.getCategoryName().equals("女装") || erpOrder.getCategoryName().equals("鞋靴") ||
						erpOrder.getCategoryName().equals("美妆护肤")) {
					priceTotall = NumberUtil.formatDouble2(totalWeight * pxECO);
					shippingVo.setBestType(9);
				} else if (erpOrder.getBrand().contains("Coach") || erpOrder.getBrand().contains("MK")|| erpOrder.getCategoryName().equals("配饰")
						|| erpOrder.getBrand().contains("Guess") || erpOrder.getBrand().contains("Estee")|| erpOrder.getBrand().contains("NARS")
						|| erpOrder.getBrand().contains("Fresh") || erpOrder.getCategoryName().equals("流行饰品")|| erpOrder.getBrand().contains("Lancome")||erpOrder.getBrand().contains("Clinique") || erpOrder.getBrand().contains("Chanel") || erpOrder.getBrand().contains("Dior") || erpOrder.getBrand().contains("Armani") || erpOrder.getBrand().contains("Philosophy")
						|| erpOrder.getCategoryName().equals("潮流香水") || erpOrder.getCategoryName().equals("潮流彩妆") || erpOrder.getCategoryName().equals("美妆护肤") || erpOrder.getCategoryName().equals("高级护肤") || erpOrder.getCategoryName().equals("箱包皮具") || erpOrder.getCategoryName().equals("潮流女包") || erpOrder.getCategoryName().equals("时尚男包") || erpOrder.getBrand().contains("Kiehl's")) {
					priceTotall = NumberUtil.formatDouble2(totalWeight * pxTypeHUA);
					shippingVo.setBestType(21);
				} else {
					priceTotall = NumberUtil.formatDouble2(totalWeight * pxBLIF);
					shippingVo.setBestType(9);
				}
			}
		}
       /* for (ErpOrder erpOrder : ErpOrderPrice) {
        	if(erpOrder.getCategoryName().equals("鞋靴") && erpOrder.getQuantity()>1){
        		shippingVo.setBestType(8);
        	} else if (StringUtils.isBlank(erpOrder.getIdCard())){
        		shippingVo.setBestType(8);//经济A线
        	} else {
        		shippingVo.setBestType(9);
        	}
		}*/
		shippingVo.setFinallyFreight(priceTotall);
		/*if (ErpOrderPrice.size() == 1 && (ErpOrderPrice.get(0).getItemCode().equals("I0108001Q40357") || ErpOrderPrice.get(0).getItemCode().equals("I0402001Q11059"))) {
			shippingVo.setFinallyFreight(0.0);
		}*/
		return shippingVo;
	}
	
	
}
